package com.card.hwatt.controllers;

import java.io.File;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.card.hwatt.service.*;
import com.card.hwatt.assembler.EmployeeAssembler;
import com.card.hwatt.assembler.LeaveAssembler;
import com.card.hwatt.core.DataMapUntils;
import com.card.hwatt.core.ObjectUtil;
import com.card.hwatt.dto.*;

/**
 * 请假
 * @author Administrator
 *
 */
@Controller
@Scope("prototype")
@RequestMapping("/leave")
public class LeaveController extends BaseController{

	@Autowired
	@Qualifier("leaveService")
	private LeaveService leaveService;

	@Autowired
	@Qualifier("employeeService")
	private EmployeeService employeeService;

	@RequestMapping("/index")
	public String index() {
		return "leave";
	}

	@RequestMapping("/save")
	public @ResponseBody
	ReturnValue save(HttpServletRequest request, long employeeId, String value,
			String startDate, String endDate, String reason) {
		ReturnValue result = new ReturnValue();
		if (StringUtils.isEmpty(value)) {
			result.message = "请填写请假类型";
			return result;
		}

		if (StringUtils.isEmpty(startDate)) {
			result.message = "请填写开始日期";
			return result;
		}

		if (StringUtils.isEmpty(endDate)) {
			result.message = "请填写结束日期";
			return result;
		}

		List<DataMap> maps = DataMapUntils.loadAllDataMap(request);
		if (CollectionUtils.isEmpty(maps)) {
			result.message = "无请假类型";
			return result;
		}

		String key = null;
		for (DataMap dataMap : maps) {
			if (value.equals(dataMap.value)) {
				key = dataMap.key;
				break;
			}
		}

		if (StringUtils.isEmpty(key)) {
			result.message = "请假类型不正确";
			return result;
		}

		String[] parsePatterns = { "yyyy-MM-dd" };
		Date start = null, end = null;
		try {
			start = DateUtils.parseDate(startDate, parsePatterns);
			end = DateUtils.parseDate(endDate, parsePatterns);
		} catch (Exception e) {
			e.printStackTrace();
			result.message = "日期格式不正确";
			return result;
		}

		long day = (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000);
		if (day < 0) {
			result.message = "日期区间不正确";
			return result;
		}

		result = leaveService.save(employeeId, key, value, start, day, reason);
		return result;
	}

	@RequestMapping(value = "/import", method = RequestMethod.POST)
	public @ResponseBody
	PageResult<LeaveView> importData(
			@RequestParam("filedata") MultipartFile filedata,
			HttpServletRequest request) {

		PageResult<LeaveView> result = new PageResult<LeaveView>();
		result.rows = new ArrayList<LeaveView>();

		if (filedata == null || filedata.isEmpty()) {
			return result;
		}

		try {
			String realPath = request.getSession().getServletContext()
					.getRealPath("/temp");
			File dir = new File(realPath);
			if (!dir.exists()) {
				dir.mkdirs();
			}
			String path = realPath + File.separatorChar + UUID.randomUUID()
					+ ".xls";
			File file = new File(path);
			FileInputStream fis = null;
			try {
				filedata.transferTo(file);

				fis = new FileInputStream(file);
				POIFSFileSystem fs = new POIFSFileSystem(fis);
				HSSFWorkbook wb = new HSSFWorkbook(fs);
				HSSFSheet sheet = wb.getSheetAt(0);

				for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {

					HSSFRow row = sheet.getRow(i);
					LeaveView leaveView = new LeaveView();
					result.rows.add(leaveView);
					if (row != null) {
						HSSFCell cell = row.getCell(0);
						if (cell != null) {
							if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
								leaveView.employeeCode = String.valueOf(Math
										.round(cell.getNumericCellValue()));
							} else {
								leaveView.employeeCode = cell
										.getStringCellValue();
							}
						}
						cell = row.getCell(2);
						if (cell != null) {
							if (cell.getCellType() != HSSFCell.CELL_TYPE_NUMERIC) {
								leaveView.value = cell.getStringCellValue();
							}
						}

						cell = row.getCell(3);
						if (cell != null) {
							if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
								leaveView.startDay = cell.getDateCellValue();
							} else {
								String[] parsePatterns = { "yyyy/MM/dd",
										"yyyy/M/d", "yyyy/M/dd", "yyyy/MM/d",
										"yyyy-MM-dd", "yyyy-M-d", "yyyy-M-dd",
										"yyyy-MM-d", "yyyy年MM月dd日",
										"yyyy年M月d日", "yyyy年M月dd日", "yyyy年MM月d日" };
								leaveView.startDay = DateUtils.parseDate(
										cell.getStringCellValue(),
										parsePatterns);
							}
						}

						cell = row.getCell(4);
						if (cell != null) {
							if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
								leaveView.endDay = cell.getDateCellValue();
							} else {
								String[] parsePatterns = { "yyyy/MM/dd",
										"yyyy/M/d", "yyyy/M/dd", "yyyy/MM/d",
										"yyyy-MM-dd", "yyyy-M-d", "yyyy-M-dd",
										"yyyy-MM-d", "yyyy年MM月dd日",
										"yyyy年M月d日", "yyyy年M月dd日", "yyyy年MM月d日" };
								leaveView.endDay = DateUtils.parseDate(
										cell.getStringCellValue(),
										parsePatterns);
							}
						}

						cell = row.getCell(5);
						if (cell != null) {
							if (cell.getCellType() != HSSFCell.CELL_TYPE_NUMERIC) {
								leaveView.reason = cell.getStringCellValue();
							}
						}
					}
				}

			} finally {
				if (fis != null) {
					fis.close();
				}
				if (file.exists()) {
					file.delete();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		StringBuilder builder = new StringBuilder();
		List<Object> params = new ArrayList<Object>();
		for (LeaveView leaveView : result.rows) {
			builder.append(" or employeeCode = ? ");
			params.add(leaveView.employeeCode);
		}
		if (builder.length() > 0) {
			List<Employee> employeeList = EmployeeAssembler
					.convert(employeeService.loadAll(new PageParam(0, 0,
							" id != id " + builder.toString(), params,
							" employeeCode asc ")).rows);
			List<LeaveView> list = new ArrayList<LeaveView>();

			for (LeaveView item : result.rows) {
				for (Employee employee : employeeList) {
					if (item.employeeCode.equals(employee.employeeCode)) {
						LeaveView leaveView = new LeaveView();
						leaveView.startDay = item.startDay;
						leaveView.endDay = item.endDay;
						leaveView.employeeId = employee.id;
						leaveView.employeeCode = employee.employeeCode;
						leaveView.employeeName = employee.name;
						leaveView.reason = item.reason;
						leaveView.value = item.value;
						leaveView.id = UUID.randomUUID();
						list.add(leaveView);
						break;
					}
				}
			}
			result.footer = new ArrayList<LeaveView>();
			LeaveView footer = new LeaveView();
			result.footer.add(footer);
			footer.employeeCode = "共计" + result.rows.size() + "条";
			footer.employeeName = "正确数据" + list.size() + "条";

			if (list.size() != result.rows.size()) {
				footer.reason = "错误数据" + (result.rows.size() - list.size())
						+ "条";
			}
			result.rows = list;
		} else {
			result.rows.clear();
		}

		result.total = result.rows.size();
		return result;
	}

	@RequestMapping("/saveAll")
	public @ResponseBody
	ReturnValue save(String json, HttpServletRequest request) {

		ReturnValue result = new ReturnValue();

		ObjectMapper objectMapper = new ObjectMapper();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		objectMapper.setDateFormat(df);

		TypeReference<List<LeaveView>> tr = new TypeReference<List<LeaveView>>() {
		};
		try {
			List<LeaveView> list = objectMapper.readValue(json, tr);
			List<LeaveView> newList = new ArrayList<LeaveView>();
			String msg = convertNewList(list, newList, request);
			if (StringUtils.isNotEmpty(msg)) {
				result.message = msg;
				return result;
			}

			for (LeaveView leaveView : newList) {
				leaveService.save(leaveView.employeeId, leaveView.key,
						leaveView.value, leaveView.startDay, leaveView.day,
						leaveView.reason);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		result.message = "ok";
		result.isSucess = true;
		return result;
	}

	private String convertNewList(List<LeaveView> src, List<LeaveView> list,
			HttpServletRequest request) {
		List<DataMap> maps = DataMapUntils.loadAllDataMap(request);
		if (CollectionUtils.isEmpty(maps)) {
			return "无请假类型";
		}
		for (LeaveView leaveView : src) {
			if (StringUtils.isEmpty(leaveView.value)) {
				return "请填写请假类型";
			}

			if (leaveView.startDay == null) {
				return "请填写开始日期";
			}

			if (leaveView.endDay == null) {
				return "请填写结束日期";
			}

			String key = null;
			for (DataMap dataMap : maps) {
				if (leaveView.value.equals(dataMap.value)) {
					key = dataMap.key;
					break;
				}
			}

			if (StringUtils.isEmpty(key)) {
				return "请假类型不正确";
			}
			leaveView.key = key;
			long day = (leaveView.endDay.getTime() - leaveView.startDay
					.getTime()) / (24 * 60 * 60 * 1000);
			if (day < 0) {
				return "日期区间不正确";
			}
			leaveView.day = (int) day;
			LeaveView item = new LeaveView();
			ObjectUtil.fieldCopy(leaveView, item);
			list.add(item);
		}
		return null;
	}

	@RequestMapping("/saveRemove")
	public @ResponseBody
	ReturnValue save(long employeeId, String startDate, String endDate,
			String reason) {
		ReturnValue result = new ReturnValue();

		if (StringUtils.isEmpty(startDate)) {
			result.message = "请填写开始日期";
			return result;
		}

		if (StringUtils.isEmpty(endDate)) {
			result.message = "请填写结束日期";
			return result;
		}

		String[] parsePatterns = { "yyyy-MM-dd" };
		Date start = null, end = null;
		try {
			start = DateUtils.parseDate(startDate, parsePatterns);
			end = DateUtils.parseDate(endDate, parsePatterns);
		} catch (Exception e) {
			e.printStackTrace();
			result.message = "日期格式不正确";
			return result;
		}

		long day = (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000);
		if (day < 0) {
			result.message = "日期区间不正确";
			return result;
		}

		result = leaveService.save(employeeId, StringUtils.EMPTY, "补班", start,
				day, reason);
		return result;
	}

	@RequestMapping("/loadAll")
	public @ResponseBody
	PageResult<LeaveView> loadAll(Integer id, String name, String startDate,
			String endDate, int page, int rows) {
		if (id == null) {
			PageResult<LeaveView> result = new PageResult<LeaveView>();
			result.rows = new ArrayList<LeaveView>();
			return result;
		}

		PageResult<Object[]> pr = leaveService.loadAllGroup(id, name,
				startDate, endDate, page, rows);
		PageResult<com.card.hwatt.dto.LeaveView> result = LeaveAssembler
				.convertPage(pr);
		return result;
	}

	@RequestMapping("/delete")
	public @ResponseBody
	ReturnValue delete(Long employeeId, String start, String end) {
		String[] parsePatterns = { "yyyy-MM-dd" };
		try {
			Date startDate = DateUtils.parseDate(start.split(" ")[0],
					parsePatterns);
			Date endDate = DateUtils
					.parseDate(end.split(" ")[0], parsePatterns);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startDate);
			Calendar calendarEnd = Calendar.getInstance();
			calendarEnd.setTime(endDate);

			List<Object> params = new ArrayList<Object>();
			params.add(employeeId);
			StringBuilder builder = new StringBuilder();

			builder.append(" name = ? ");
			params.add(DateFormatUtils.format(calendarEnd, "yyyyMMdd"));

			for (; calendar.before(calendarEnd); calendar.add(Calendar.DATE, 1)) {
				String date = DateFormatUtils.format(calendar, "yyyyMMdd");
				params.add(date);
				builder.append(" or name = ? ");
			}

			List<Leave> list = LeaveAssembler
					.convert((leaveService.loadAll(new PageParam(0, 0,
							" employee.id = ? and ( " + builder.toString()
									+ " )", params, " date desc ")).rows));
			for (Leave leave : list) {
				leaveService.delete(leave.id);
			}
			ReturnValue result = new ReturnValue();
			result.message = "ok";
			result.isSucess = true;
			return result;
		} catch (Exception e) {
			ReturnValue result = new ReturnValue();
			result.message = "错误";
			return result;
		}
	}
}
